-- World
-- 世界控制

World = class()

function World:init()
    self.objects = {}
    self.allObjects = {}
end

function World:clear()
    for k,body in pairs(self.objects) do
        body:destroy()
    end
    self.allObjects = {self.ground}
    self.objects = {}
end

function World:addObject(obj)
    table.insert(self.objects,obj)
    table.insert(self.allObjects,obj)
end

function World:addGround()
    self.ground = Object.Floor:createBody(0,0,_,0,5,WIDTH,5)
    table.insert(self.allObjects,self.ground)
end

function World:removeObject(index_or_object)
    if type(index_or_object) == "number" then
        self.objects[index_or_object]:destroy()
        table.remove(self.objects,index_or_object)
        table.remove(self.allObjects,index_or_object)
    else
        for k,body in pairs(self.objects) do
            if body == index_or_object then
                index_or_object:destroy()
                table.remove(self.objects,k)
                return
            end
        end
        for k,body in pairs(self.allObjects) do
            if body == index_or_object then
                if index_or_object then
                    index_or_object:destroy()
                end
                table.remove(self.allObjects,k)
                return
            end
        end
    end
end

function World:getObjectCount()
    return #self.objects
end

function World:draw()
    pushStyle()
    noSmooth()
    rectMode(CENTER)
    ellipseMode(CENTER)
    
    for k,body in pairs(self.allObjects) do
        if self:shouldRenderObject(body) then
            body:draw()
        end
    end
    popStyle()
    ---------------------- 设置 ---------------------
    if SettingList.ShowDebugCollision then
        pushStyle()
        smooth()
        ellipseMode(RADIUS)
        for k,body in pairs(self.allObjects) do
            if self:shouldRenderObject(body) then
                game.gui.debugs:drawCollisionBox(body)
            end
        end
        popStyle()
    end
    ----------------------------------------------------
end

-- 简单粗暴的判断是否要渲染物体
function World:shouldRenderObject(body)
    if body.x < -100 or body.y > HEIGHT + 100 or body.x > WIDTH + 100 or body.y < -100 then
        return false
    else
        return true
    end
end

function World:tick()
    if game.mode.tick then
        game.mode.tick(self)
    end
    
    ---------------------------- 风扇AABB -------------------------
    for k,body in pairs(self.objects) do
        if body.id == Object.Fan.id then
            particleList:addParticleAtPos(body.x,body.y)
            self.aabbFanX = vec2(body.x + body.w - 30,body.y - 30)
            self.aabbFanY = vec2(body.x + body.w * 2,body.y + 30)
            q = physics.queryAABB(self.aabbFanX,self.aabbFanY)
            for k,v in pairs(q) do
                v:applyForce(vec2(body.x, body.y))
            end
        end
    end
    ---------------------------------------------------------------
end

--------------------------  施加力的类型 --------------------------
function World:applyForceToAllObject(force)
    for k,body in pairs(self.objects) do
        body:applyForce(force)
    end
end

function World:setAttributeTotAllObject(func)
    for k,body in pairs(self.objects) do
        func(body)
    end
end

function World:explode(position,radius,strength)
    for k,body in pairs(self.objects) do
        if body.applyForce then
            body:applyForce(Force.calcExplode(self,body,position,radius,strength))
        end
    end
end
-------------------------------------------------------------------


------------------ 开发者dt教你读懂PB的读取与存储 -----------------
function World:save(saveFileName)
    self.saveName = saveFileName
    local list = {} -- 建立一个临时新表
    for k,body in pairs(self.objects) do
        table.insert(list,{body.id,body.x,body.y,body.angle}) -- 往表里存入重要信息（id，x，y，angle）
    end
    saveText("Project:"..self.saveName,table.tostring(list)) -- 使用table.tostring（codea.io网友制作）把表转成字符串存储
end

function World:autoSave(saveFileName)
    if math.floor(ElapsedTime) % 30 == 0 then -- 每30秒自动存储
        self:save(saveFileName)
    end
end

function World:read(readFileName)
    self:clear()
    
    local file = "Project:"..readFileName
    local p = readText(file)
    if p == nil or p == " " then
        saveText(file," ") -- 如果表是空的话，加一个空格以防止报错
    else
        p = readText(file)
        local ts = string.totable(p) -- 把提取出字符串用string.totable（codea.io网友自制）把字符串转成表
        for i = 1,#ts do
            self:addObject(Object.objects[ts[i][1]]:createBody(ts[i][2],ts[i][3],ts[i][4]))
            -- 添加物品（ts[i][1] = id,ts[i][2] = x,ts[i][3] = y,ts[i][4] = angle)
        end
    end
end

function World:getSaveList()
    local list = assetList("Project",TEXT)
    local result = {}
    local txt
    for k,v in pairs(list) do
        txt = readText("Project:"..v)
        if txt ~= nil and txt ~= "" then
            table.insert(result,v)
        end
    end
    return result
end

function World:pause()
    physics.pause()
end

function World:resume()
    physics.resume()
end
